home *** CD-ROM | disk | FTP | other *** search
- ;MACROS for items that replace BIOS calls
- ;
- ; Prolog Segname
- ; start of code should be labeled
- ; ENTRY:
- ;
- ; Epilog IntNo,Pointr,SegName
- ; IntNo is interrupt number
- ; Pointr is name of data area DD
- ;
- ; Finish SegName,StackSize
- ; the variable zzarg gets set to the first word (two chars) entered
- ; on the command line
- ;
- ; Finish has first label of CONFIG:
- ; if HIMSG exists it is printed (put after Epilog)
- ; eg jmp CONFIG
- ; HIMSG db 'hello$'
-
-
- ; Prolog SegName
- ; This pushes a bit and then runs to the rest
- ; name the segment here
-
- Prolog MACRO SegName
- pBase equ 00h ;pBase of memory (seg)
- zbufr equ 5Dh
-
-
-
- DGROUP GROUP SegName,ZzUseStk
-
- SegName Segment para
-
- Moveit PROC FAR
- ASSUME CS:SegName
-
- ;Set up the stack so a RET instruction
- ; will jump to the
- ; beginning of program segment
- push ds ;Prog segment
- xor ax,ax
- push ax ;Offset
-
- jmp DoTheRest
-
- db '1982 MSZachmann'
- MoveIt endp
- ENDM
- ; Epliog IntNo,Pointr
- ;
- ; This does the work of checking
- ; that no other one has been loaded.
- ; Just exits if other loaded. IntNo
- ; is the interrupt number
- ; Pointer is a pointer to where the
- ; old address should be stored.
-
-
- Epilog MACRO IntNo,Pointr,SegName
- EndEntry label near
-
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ;
- ; Temporary stuff
- ;
- ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-
- Initial proc near
- DoTheRest LABEL NEAR
-
- ;Check to see if already loaded.
- ; if so, exit
- ;
- mov BX,zbufr
- mov AX,[BX]
- mov CS:zzarg,AX
- push DS
- mov AX,pBase
- mov DS,AX
- mov BX,4*IntNo
- LES SI,dword ptr [BX]
- ;now have start address of code
- mov SI,offset ENTRY ;start here
- mov DI,SI
- mov AX,CS
- mov DS,AX ; all set for compare
- CLD ;forward
- mov CX,010 ;should suffice
- REPE CMPSW
- pop DS
- ; now set status byte to 0FFFh
- mov AX,0FFFFh
- push AX
- jne short Nxt1
- jmp Config
-
-
- ;Modify the INT 20H instruction at DS:1
- ; Make it an INT 27h
- Nxt1: mov BX,1
- mov BYTE PTR [BX],27h
-
- ;relocate down a page using CS:->DS:
- ;
- mov AX,DS
- mov ES,AX ;set ES to page lower
- mov AX,CS
- mov DS,AX ;set DS to here
- mov SI,offset ENTRY
- mov DI,SI ;both same
- mov CX,offset EndEntry-offset ENTRY
- shr CX,1 ;div by 2 for wds
- inc CX ;for luck
- lz1: rep movsw
- and CX,CX
- jnz lz1
-
- ;Set DS:BX to point to int vector IntNo
- ; (Pointr i/o )
- MOV AX,pBase
- MOV DS,AX
- MOV BX,4*IntNo
-
-
- push ES ;save new page
-
- ;Set ES:DI to old vector 10h
- LES DI,DWORD PTR [BX]
-
- ;Reset the vector to Entry point
- MOV WORD PTR [BX],offset ENTRY
- pop CX ;new page number
- MOV WORD PTR [BX+2],CX
-
- ;Now put the old vector address
- ; into the call pointer at
- ; DS:Pointr
- ASSUME DS:&SegName
- ;actually DS is SegName-100h
- MOV DS,CX
- MOV Pointr,DI
- MOV Pointr+2,ES
- ;set status to NEW
- pop AX ;get status back
- xor AX,AX
- push AX ;for later
- Initial endp
-
- ENDM
-
- ; Finish
- ; exits
- ; takes segment name and stack size
-
- Finish MACRO SegName,SSizez
-
-
- ;Set up DX to the program size, note
- ; that CS is 100h larger than
- ; program prefix segment
- ; ! This is the lazy way, and
- ; assumes PC-DOS stays consistent.
-
- Nconfig proc far
- CONFIG label near
- mov AX,CS
- mov DS,AX ;for print screen
- IFDEF HIMSG
- mov AH,9 ;print string
- mov DX,offset CLearstr
- int 21h ;DOS
- mov DX,offset HIMSG
- int 21h
- ENDIF
-
- pop AX ;get status
- and AX,AX ;if zero then new
- jz CONF3
- mov DX,offset AlThere
- mov AH,9
- int 21h ;print
- CONF3: MOV DX,offset endENTRY
- RET ;Exit from the system
- ;By doing an INT 27h
- ALThere db '*** This program was already loaded. ***',13,10,'$'
- zzarg dw ? ;will contain first word at 80h
- Clearstr db 13
- db 27 dup(10)
- db '$'
- Nconfig endp
-
-
-
- SegName ends
-
- ; ensure that stack gets loaded highest in memory
- ; by naming it large (ZZ...)
-
- ZzUSERST segment STACK
- dw SSizez dup (?)
- ZzUSERST ENDS
-
-
- ENDM
-
- RST ENDS
-
-
- ENDM
-
-